<template>
  <fui-drawer class="ui-multilevel-picker" :zIndex="999" :show="visible" :style="`top: ${store.getters.statusBarHeight}px`">
    <view class="ui-multilevel-header">
      <fui-search-bar radius="36" paddingTb="22" :paddingLr="36" :placeholder="searchText" :isLeft="true" searchText="" :cancel="false" @input="search">
        <fui-icon name="arrowleft" size="60" color="#666" @click="close"></fui-icon>
      </fui-search-bar>
    </view>
    <view class="ui-multilevel-content">
      <scroll-view class="ui-multilevel-list" scroll-y :class="{'single': maxLevel <= 1}" v-for="i in maxLevel" :key="i">
        <view class="ui-multilevel-item" :class="{'active': item.isActive}" v-for="item in getPickerColumnList(i)" :key="item.value">
          <fui-text v-if="maxLevel <= 1" class="ui-multilevel-item__text" :text="item.text" @click="onItemCheck(item)"></fui-text>
          <fui-text v-else class="ui-multilevel-item__text" :text="item.text" @click="onItemClick(item)"></fui-text>
          <template v-if="(maxLevel > 1 && i > 1) || (maxLevel <= 1)">
            <image v-if="item.status === 'all' && item.disabled" src="/static/images/checked-disabled.png" class="ui-multilevel-item__status" @click="onItemCheck(item)"></image>
            <image v-else-if="item.status === 'all'" src="/static/images/checked-all.png" class="ui-multilevel-item__status" @click="onItemCheck(item)"></image>
            <image v-else-if="item.status === 'some'" src="/static/images/checked-some.png" class="ui-multilevel-item__status" @click="onItemCheck(item)"></image>
            <image v-else src="/static/images/checked-none.png" class="ui-multilevel-item__status" @click="onItemCheck(item)"></image>
          </template>
        </view>
      </scroll-view>
    </view>
    <view class="ui-multilevel-footer">
      <fui-button class="ui-btn-grey" text="清空选择" height="88rpx" radius="44rpx" @click="clear"></fui-button>
      <fui-button text="确定" height="88rpx" radius="44rpx" @click="submit"></fui-button>
    </view>
  </fui-drawer>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()

const props = defineProps({
  searchText: {
    type: String,
    default: '请输入名称检索'
  },
  searchType: {
    type: String,
    default: 'region'
  },
  defaultProps: {
    type: Object,
    default: {
      text: 'text',
      value: 'value',
      children: 'children'
    }
  },
  maxLevel: {
    type: Number,
    default: 3
  },
  data: {
    type: Array,
    default: []
  },
  cacheData: {
    type: Array,
    default: []
  }
})

const emits = defineEmits(['submit'])

const pickerList = ref([])
const tempPickedList = ref([])
const visible = ref(false)
const show = () => {
  visible.value = true
  init()
}
const close = () => {
  visible.value = false
}

// 点击当前项
const onItemClick = (obj => {
  if (!obj || props.maxLevel <= 1) return
  if (obj.text === '全部' || obj.level === level.value) return

  pickerList.value.forEach(item => {
    // 显示/隐藏
    item.isShow = false
    if (item.parentArr && obj.parentArr.toString().indexOf(item.parentArr.toString()) > -1) {
      item.isShow = true
    }
    if (item.parent === obj.value) {
      item.isShow = true
    }
    if (item.text === '全部' && item.level <= obj.level + 1) {
      item.isShow = true
    }

    // active状态
    item.isActive = false
    if (item.value === obj.value) {
      item.isActive = true
    }
    if (obj.parentArr.indexOf(item.value) > -1) {
      item.isActive = true
    }
  })

  // 全部处理
  const allObj = pickerList.value.find(item => item.level === obj.level + 1 && item.text === '全部')
  if (allObj) {
    const activeParentObj = pickerList.value.find(item => item.level === obj.level && item.isActive)
    const activeChildList = pickerList.value.filter(item => item.parent === activeParentObj.value)
    const activeChildCheckedList = activeChildList.filter(item => item.checked)

    if (!activeChildCheckedList.length) {
      allObj.checked = false
      allObj.status = 'none'
    } else if (activeChildCheckedList.length === activeChildList.length) {
      allObj.checked = true
      allObj.status = 'all'
    } else {
      allObj.checked = false
      allObj.status = 'some'
    }
  }
})

// 临时数据处理
const onItemDeal = (obj) => {
  const index = tempPickedList.value.findIndex(item => item.value === obj.value)
  if (obj.checked) {
    if (index < 0) tempPickedList.value.push(obj)
  } else {
    tempPickedList.value = tempPickedList.value.filter(a => a.value !== obj.value)
  }
}

// 勾选当前项
const onItemCheck = (obj) => {
  if (obj.disabled) return
  obj.checked = !obj.checked
  obj.status = obj.checked ? 'all' : 'none'
  onItemDeal(obj)

  if (obj.text === '全部') {
    // 勾选同级&&下级
    const activeParentObj = pickerList.value.find(item => item.level === obj.level - 1 && item.isActive)
    const activeChildList = pickerList.value.filter(item => item.parentArr && item.parentArr.indexOf(activeParentObj.value) > -1)
    activeChildList.forEach(item => {
      item.checked = obj.checked
      item.status = obj.status
      onItemDeal(item)
    })
  } else {
    // 勾选下级
    const lowerList = pickerList.value.filter(item => item.parentArr && item.parentArr.indexOf(obj.value) > -1)
    lowerList.forEach(item => {
      item.checked = obj.checked
      item.status = obj.status
      onItemDeal(item)
    })
  }

  // 上级处理
  const upperList = pickerList.value.filter(item => item.level < obj.level && item.isActive).reverse()
  upperList.forEach(item => {
    const itemChildList = pickerList.value.filter(subitem => subitem.parent === item.value)
    const itemChildCheckedList = itemChildList.filter(subitem => subitem.checked)
    if (itemChildList.length) {
      if (!itemChildCheckedList.length) {
        item.checked = false
        item.status = 'none'
      } else if (itemChildCheckedList.length === itemChildList.length) {
        item.checked = true
        item.status = 'all'
      } else {
        item.checked = false
        item.status = 'some'
      }
    } else {
      item.checked = obj.checked
      item.status = obj.status
    }
    onItemDeal(item)
  })

  // 全部处理
  const allList = pickerList.value.filter(item => item.text === '全部')
  allList.forEach(item => {
    const activeParentObj = pickerList.value.find(subitem => subitem.level === item.level - 1 && subitem.isActive) || {}
    const activeChildList = pickerList.value.filter(subitem => subitem.parent === activeParentObj.value)
    const activeChildCheckedList = activeChildList.filter(subitem => subitem.checked)
    if (activeChildList.length) {
      if (!activeChildCheckedList.length) {
        item.checked = false
        item.status = 'none'
      } else if (activeChildCheckedList.length === activeChildList.length) {
        item.checked = true
        item.status = 'all'
      } else {
        item.checked = false
        item.status = 'some'
      }
    } else {
      item.checked = obj.checked
      item.status = obj.status
    }
  })
}

// 数据平铺
let level = ref(0)
const getPickerList = (data, curLevel, curParent, curParentArr) => {
  let list = []
  const parentArr = curParentArr ? curParentArr : []
  data.forEach(item => {
    item.level = curLevel ? curLevel + 1 : 1
    item.parent = curParent ? curParent : '00'
    item.parentArr = [...parentArr, item.parent]
    if (level.value < item.level) level.value++
    list.push({
      text: item[props.defaultProps.text],
      value: item[props.defaultProps.value],
      level: item.level,
      parent: item.parent,
      parentArr: item.parentArr,
      isActive: false,
      isShow: props.maxLevel <= 1,
      checked: false,
      status: 'none'
    })
    if (item.children && item.children.length) {
      const arr = getPickerList(item[props.defaultProps.children], item.level, item[props.defaultProps.value], item.parentArr)
      list = list.concat(arr)
    }
  })
  return list
}

// 数据初始化
const init = () => {
  if (props.cacheData.length) {
    pickerList.value = props.cacheData
    tempPickedList.value = pickerList.value.filter(item => item.checked)
  } else {
    tempPickedList.value = []
    pickerList.value = getPickerList(props.data)
    pickerList.value = pickerList.value.filter(item => item.level <= props.maxLevel)
    for (let i = 2; i <= props.maxLevel; i++) { // 添加全部
      pickerList.value.unshift({
        text: '全部',
        value: 'all-' + i,
        level: i,
        isActive: false,
        isShow: false,
        checked: false,
        status: 'none'
      })
    }
  }
  onItemClick(pickerList.value[props.maxLevel - 1]) // 默认active
}

// 获取当前列数据
const getPickerColumnList = (curLevel) => {
  return pickerList.value.filter(item => item.level === curLevel && item.isShow)
}

// 搜索
const search = (e) => {
  const searchText = e.detail.value
  pickerList.value.forEach(item => {
    item.isShow = !searchText
  })
  const conditionList = pickerList.value.filter(item => item.text.toLowerCase().indexOf(searchText.toLowerCase()) > -1)
  conditionList.forEach(item => {
    item.isShow = true

    const parentList = pickerList.value.filter(subitem => subitem.parentArr && item.parentArr && item.parentArr.indexOf(subitem.value) > -1)
    parentList.forEach(subitem => {
      subitem.isShow = true
    })
  })
}

// 清空
const clear = () => {
  pickerList.value.forEach(item => {
    if (!item.disabled) {
      item.checked = false
      item.status = 'none'
    }
  })
}

// 提交
const submit = () => {
  const pickedList = []
  tempPickedList.value.map(item => {
    const itemParent = tempPickedList.value.find(subitem => subitem.value === item.parent) || {}
    if (item.text !== '全部' && item.checked && !itemParent.checked) {
      pickedList.push({
        text: item.text,
        value: item.value
      })
    }
  })
  close()
  const result = {
    data: pickedList,
    text: pickedList.map(item => item.text).join(','),
    value: pickedList.map(item => item.value).join(','),
    label: pickedList.map(item => item.text + ',' + item.value).join('|'),
    cacheData: pickerList.value
  }
  emits('submit', result)
}

defineExpose({
  show
})
</script>

<style lang='scss' scoped>
.ui-multilevel-picker {
  ::v-deep .fui-drawer__popup {
    width: 100%;
  }
  ::v-deep .fui-search__bar-wrap {
    padding-left: 0 !important;
    .fui-search__bar-icon {
      position: absolute;
      top: 50%;
      right: 40rpx;
      margin-top: -20rpx;
      .fui-sbi__circle {
        border-color: var(--fui-color-primary);
      }
      .fui-sbi__line {
        background-color: var(--fui-color-primary);
      }
    }
    .fui-sbi__clear-wrap {
      display: none;
    }
  }
  .fui-drawer__popup {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  .ui-multilevel-content {
    flex: 1;
    display: flex;
    justify-content: space-between;
    overflow: hidden;
    .ui-multilevel-list {
      flex: 1;
      overflow: auto;
      border-left: 2rpx solid #f3f3f3;
      .ui-multilevel-item {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 24rpx 36rpx;
        &.active {
          ::v-deep .ui-multilevel-item__text {
            .fui-text__content {
              color: var(--fui-color-primary) !important;
            }
          }
        }
        .ui-multilevel-item__status {
          flex: 0 0 28rpx;
          width: 28rpx;
          height: 28rpx;
          margin-left: 10rpx;
        }
      }
      &:nth-child(1) {
        background-color: #f8f8f8;
        .ui-multilevel-item.active {
          position: relative;
          background-color: #fff;
          font-weight: bold;
          color: var(--fui-color-primary);
          &::before {
            position: absolute;
            content: "";
            top: 50%;
            left: 0;
            width: 8rpx;
            height: 48rpx;
            background-color: var(--fui-color-primary);
            border-radius: 0 16rpx 16rpx 0;
            transform: translateY(-50%);
          }
        }
      }
      &.single {
        background-color: #fff;
        .ui-multilevel-item {
          flex-direction: row-reverse;
          &.active::before {
            display: none;
          }
          .fui-text__wrap {
            flex: 1;
            margin-left: 20rpx;
          }
        }
      }
    }
  }
  .ui-multilevel-footer {
    z-index: 10;
    display: flex;
    justify-content: space-between;
    box-shadow: 0rpx 2rpx 6rpx 2rpx rgba(0, 0, 0, 0.16);
    background-color: #fff;
    padding: 24rpx 36rpx;
    .ui-btn-grey {
      flex: 0 0 230rpx;
      margin-right: 40rpx !important;
    }
  }
}
</style>